'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const port = 8089 // 前端本地启动的端口号

function resolve(dir) {
  return path.join(__dirname, dir)
}
module.exports = {
  publicPath: process.env.VUE_APP_BASE_ROUTER_NAME, // 打包的路径
  outputDir: process.env.outputDir, // 当运行 vue-cli-service build 时生成的生产环境构建文件的目录。注意目标目录在构建之前会被清除 (构建时传入 --no-clean 可关闭该行为)。
  assetsDir: 'static', // 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
  lintOnSave: false, // 设置为 true 时，eslint-loader 会将 lint 错误输出为编译警告。默认情况下，警告仅仅会被输出到命令行，且不会使得编译失败。如果你希望让 lint 错误在开发时直接显示在浏览器中，你可以使用 lintOnSave: 'error'。这会强制 eslint-loader 将 lint 错误输出为编译错误，同时也意味着 lint 错误将会导致编译失败。
  productionSourceMap: false, // 如果你不需要生产环境的 source map，可以将其设置为 false 以加速生产环境构建。
  runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了，但是这会让你的应用额外增加 10kb 左右。

  // CSS 相关选项
  css: {
    // 将组件内的 CSS 提取到一个单独的 CSS 文件 (只用在生产环境中)
    extract: true,

    // 是否开启 CSS source map？
    sourceMap: false,

    // 为预处理器的 loader 传递自定义选项。比如传递给
    // sass-loader 时，使用 `{ sass: { ... } }`。
    loaderOptions: {},

    // 为所有的 CSS 及其预处理文件开启 CSS Modules。
    // 这个选项不会影响 `*.vue` 文件。
    modules: false
  },

  // arallel: require('os').cpus().length > 1,

  // 配置 webpack-dev-server 行为。
  // 如果你的前端应用和后端 API 服务器没有运行在同一个主机上，你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。
  devServer: {
    open: process.platform === 'darwin', // 告诉dev-server在服务器启动后打开浏览器。将其设置true为打开默认浏览器
    // host: '0.0.0.0',//启用webpack的热模块更换功能：
    host: '127.0.0.1', // 启用webpack的热模块更换功能：
    port: port, // 当您拥有单独的API后端开发服务器并且希望在同一域上发送API请求时，代理某些URL可能会很有用。开发服务器使用功能强大的http-proxy-middleware软件包。查看其文档以了解更多高级用法。请注意，某些http-proxy-middleware功能不需要target键，例如其router功能，但是您仍然需要target在此处的配置中包含键，否则webpack-dev-server不会将其传递给http-proxy-middleware）。在上localhost:3000启用后端，您可以使用它启用代理
    https: false, // https被启用。
    disableHostCheck: true, // 如果hostname不是配置内的就不能访问(跳过检查)
    hotOnly: false, // 启用热模块替换（请参阅devServer.hot参考资料），而不会在构建失败时将页面刷新作为后备。
    // 查阅 https://github.com/vuejs/vue-doc-zh-cn/vue-cli/cli-service.md#配置代理
    proxy: {
      // change xxx-api/login => mock/login
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      '/api': {
        target: 'https://city.qa.crservice.cn', // 登陆
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      },
      [process.env.VUE_APP_BASE_API]: {
        target: `http://http://127.0.0.1:${port}/mock`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      }
    },
    after: require('./mock/mock-server.js'), // 提供在服务器内部在所有其他中间件之后执行自定义中间件的功能。
    before: app => {
      // `app` 是一个 express 实例
    }
  },

  configureWebpack: config => { // 如果这个值是一个对象，则会通过 webpack-merge 合并到最终的配置中。如果这个值是一个函数，则会接收被解析的配置作为参数。该函数及可以修改配置并不返回任何东西，也可以返回一个被克隆或合并过的配置版本。
    if (process.env.NODE_ENV === 'production') {
      return {
        plugins: [
          new BundleAnalyzerPlugin({
            analyzerMode: 'disabled', // 不启动展示打包报告的http服务器
            generateStatsFile: false // 是否生成stats.json文件
          })
        ]
      }
    }
    /* if (process.env.NODE_ENV === "production") {
            // 为生产环境修改配置...
            config.externals = {
                vue: "Vue",
                vuex: "Vuex",
                "vue-router": "VueRouter",
                "element-ui": "ELEMENT"
            };
        } else {
            // 为开发环境修改配置...
        }*/
    if (process.env.NODE_ENV === 'development') {
      config.devtool = 'source-map'
    } else if (process.env.NODE_ENV === 'production') {
      // 为生产环境修改配置...
      config.externals = {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        'element-ui': 'ELEMENT'
      }
      config.devtool = 'eval-source-map'
    }
  },
  chainWebpack: config => {
    config.plugin('html').tap(args => {
      args[0].template = process.env.template
      return args
    })

    // set svg-sprite-loader
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      }).end()

    // set preserveWhitespace
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.preserveWhitespace = true
        return options
      }).end()
    // https://webpack.js.org/configuration/devtool/#development
    config.when(process.env.NODE_ENV === 'development',
      config => config.devtool('cheap-source-map')
    )

    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
              // `runtime` must same as runtimeChunk name. default is `runtime` ` runtime`必须与runtimechunk名称相同。默认值为“runtime”`
              inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent 仅打包最初依赖的第三方
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package 将elementui拆分为一个包
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app 重量必须大于libs和app，否则将打包成libs或app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm 为了适应cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules   可以自定义规则
                  minChunks: 3, //  minimum common number 最小公共数
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          config.optimization.runtimeChunk('single')
        }
      )
  }
}
